package com.wb.system.service.impl;


import com.wb.common.core.domain.model.LoginUser;
import com.wb.common.exception.ServiceException;
import com.wb.common.vo.*;
import com.wb.system.domain.*;
import com.wb.system.mapper.ExamsMapper;
import com.wb.system.mapper.ExamsRecordsMapper;
import com.wb.system.mapper.QuestionMapper;
import com.wb.system.mapper.UserWrongMapper;
import com.wb.system.service.ExamsService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.wb.common.utils.SecurityUtils.getLoginUser;

@Service
public class ExamsServiceImpl implements ExamsService {

    @Autowired
    private ExamsMapper examsMapper;
    @Resource
    private ExamsRecordsMapper examsRecordsMapper;
    @Resource
    private UserWrongMapper userWrongMapper;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public List<ExamsEntity> selectExamsList(ExamsModelVO examsModelVO) {
        return examsMapper.selectExamsList(examsModelVO);
    }

    @Override
    public ExamsEntity selectById(Long id) {
        return examsMapper.selectById(id);
    }

    @Override
    public void saveExams(ExamsEntity examsEntity) {
        examsMapper.saveExams(examsEntity);
    }

    @Override
    public void updateExamsById(ExamsEntity examsEntity) {
        examsMapper.updateExamsById(examsEntity);
    }

    @Override
    public void removeExamsByIds(List<Long> ids) {
        if (ids != null && ids.size() > 0) {
            for (Long id : ids) {
                examsMapper.removeExamsById(id);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String examsStart(Long id) {
        ExamRecordsEntity examRecordsEntity = new ExamRecordsEntity();
        examRecordsEntity.setStartedAt(LocalDateTime.now());
        examRecordsEntity.setExamId(String.valueOf(id));
        LoginUser loginUser = getLoginUser();
        examRecordsEntity.setUserId(String.valueOf(loginUser.getUserId()));
        examsRecordsMapper.saveExamRecord(examRecordsEntity);
        return examRecordsEntity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean examsSubmit(ExamsSubmitVO examsSubmitVO) {
        ExamRecordsEntity examRecordsEntity = examsRecordsMapper.selectById(examsSubmitVO.getRecordId());
        if (examRecordsEntity == null) {
            throw new ServiceException("开始记录不存在！");
        }
        if (examRecordsEntity.getFinishedAt() != null) {
            throw new ServiceException("已提交过！");
        }
        examRecordsEntity.setFinishedAt(LocalDateTime.now());
        LoginUser loginUser = getLoginUser();
        examRecordsEntity.setCreateBy(loginUser.getUserId().toString());
        examsRecordsMapper.updateExamRecordById(examRecordsEntity);
        List<ExamRecordDetailReqVO> reqList = examsSubmitVO.getRecordDetailReqVOS();
        List<ExamRecordDetailEntity> entityList = new ArrayList<>();
        //题目
        if (CollectionUtils.isNotEmpty(reqList)) {
            for (ExamRecordDetailReqVO req : reqList) {
                ExamRecordDetailEntity entity = new ExamRecordDetailEntity();
                BeanUtils.copyProperties(req, entity);
                entity.setRecordId(examsSubmitVO.getRecordId().toString());
                entityList.add(entity);
            }
            examsRecordsMapper.addExamRecordDetail(entityList);
        }
        //核对答案

//        threadPoolTaskExecutor.submit(new Runnable() {
//            @Override
//            public void run() {
//                checkExamsQuestion(examsSubmitVO, loginUser.getUserId());
//            }
//        });
        checkExamsQuestion(examsSubmitVO, loginUser.getUserId());
        return true;
    }

    private void checkExamsQuestion(ExamsSubmitVO examsSubmitVO, Long userId) {
        List<ExamRecordDetailReqVO> reqList = examsSubmitVO.getRecordDetailReqVOS();
        ExamRecordsEntity examRecordsEntity = examsRecordsMapper.selectById(examsSubmitVO.getRecordId());
        if (CollectionUtils.isEmpty(reqList)) {
            examRecordsEntity.setPassed("0");
            examRecordsEntity.setScore("0");
            examsRecordsMapper.updateExamRecordById(examRecordsEntity);
        } else {
            BigDecimal score = new BigDecimal(0);
            List<ExamRecordDetailEntity> entities = examsRecordsMapper.selectExamRecordDetailList(examsSubmitVO.getRecordId());
            for (ExamRecordDetailEntity entity : entities) {
                QuestionEntity questionEntity = questionMapper.selectById(Long.valueOf(entity.getQuestionId()));
                if (questionEntity == null) {
                    continue;
                }
                if (entity.getUserAnswer().equals(questionEntity.getAnswer())) {
                    entity.setIsCorrect(1);
                    BigDecimal add = new BigDecimal(questionEntity.getScore() == null ? "0" : questionEntity.getScore());
                    score = score.add(add);
                } else {
                    //错题集
                    WrongQuestionsEntity request = new WrongQuestionsEntity();
                    request.setUserId(userId.toString());
                    request.setQuestionId(questionEntity.getId().toString());
                    WrongQuestionsEntity wrongQuestions = userWrongMapper.selectByUserIdAndId(request);
                    if (wrongQuestions == null) {
                        WrongQuestionsEntity wrongQuestionsEntity = new WrongQuestionsEntity();
                        wrongQuestionsEntity.setUserId(String.valueOf(userId));
                        wrongQuestionsEntity.setQuestionId(questionEntity.getId().toString());
                        wrongQuestionsEntity.setLastTime(LocalDateTime.now());
                        wrongQuestionsEntity.setWrongTimes(1);
                        userWrongMapper.save(wrongQuestionsEntity);
                    } else {
                        wrongQuestions.setWrongTimes(wrongQuestions.getWrongTimes() + 1);
                        wrongQuestions.setLastTime(LocalDateTime.now());
                        userWrongMapper.updateWrongQuestionsById(wrongQuestions);
                    }

                }
            }
            examsRecordsMapper.batchUpdateExamRecordDetail(entities);
            examRecordsEntity.setScore(String.valueOf(score));
            if (score.compareTo(new BigDecimal(60)) == 1) {
                examRecordsEntity.setPassed("1");
            } else {
                examRecordsEntity.setPassed("0");
            }
            examsRecordsMapper.updateExamRecordById(examRecordsEntity);
        }

    }

    @Override
    public ExamRecordVO examsResults(Long id) {
        ExamRecordVO vo = new ExamRecordVO();
        ExamRecordsEntity examRecordsEntity = examsRecordsMapper.selectById(id);
        List<ExamRecordDetailEntity> examRecordsDetailEntity = examsRecordsMapper.selectExamRecordDetailList(id);
        vo.setExamRecordsEntity(examRecordsEntity);
        vo.setRecordDetailEntities(examRecordsDetailEntity);
        return vo;
    }

    @Override
    public List<ExamRecordsEntity> history(ExamsHistoryModelVO vo) {
        LoginUser loginUser = getLoginUser();
        vo.setUserId(loginUser.getUserId().toString());
        return examsRecordsMapper.selectExamsHistoryList(vo);
    }

    @Override
    public ExamsStatsStatistic stats(ExamsStatsModelVO vo) {
        LoginUser loginUser = getLoginUser();
        vo.setUserId(loginUser.getUserId().toString());
        return examsRecordsMapper.selectExamsStatsStatisticByUserId(vo);
    }

    @Override
    public List<WrongQuestionsEntity> wrongQuestions(ExamsWrongQuestionsModelVO vo) {
        LoginUser loginUser = getLoginUser();
        vo.setUserId(String.valueOf(loginUser.getUserId()));
        return userWrongMapper.wrongQuestions(vo);
    }

    @Override
    public List<ExamsTypeStatsStatistic> typeStats(ExamsStatsModelVO vo) {
        LoginUser loginUser = getLoginUser();
        vo.setUserId(String.valueOf(loginUser.getUserId()));
        return examsRecordsMapper.typeStats(vo);
    }

    @Override
    public ExamsStatsQuestionStatistic statsQuestion(ExamsStatsQuestionModelVO vo) {
        return examsRecordsMapper.statsQuestion(vo);
    }
}
